﻿#region License statement
// NJamb, a specification and delta-specification DSL
// Copyright (c) 2010-2011, Mark Knell
// Published under the MIT License; all other rights reserved
#endregion

#region using...
using System;
using System.Linq;
using NJamb.Parser.SpecificationBuilders.SubjectHas.Extensions;
using NJamb.Parser.SubjectBuilders;
using NUnit.Framework;
using Stile.Patterns.SelfDescribingPredicates;
#endregion

namespace NJamb.Tests.Parser.SpecificationBuilders.SubjectHas
{
    [TestFixture]
    public class MinOfFixture
    {
        private const int Expected = 2;
        private const int Bogus = 3;
        private const int LowEnoughButNotInSet = 1;

        private readonly int[] _ints = new[] {Bogus, 5, Expected};

        [Test]
        public void HappyPath()
        {
            Assert.That(_ints.Min(), Is.EqualTo(Expected).And.Not.EqualTo(Bogus), "Precondition");
            Assert.That(_ints.Contains(Expected), Is.True, "Precondition");
            // arrange

            // act
            IEvaluation evaluation = Specify.For(() => _ints).ThatTheSequence(x => x).Has.MinOf(Expected).Evaluate();

            // assert
            Assert.That(evaluation.Success, Is.True);
        }

        [Test]
        public void RejectsNonMember()
        {
            // arrange
            Assert.That(LowEnoughButNotInSet, Is.LessThan(_ints.Min()), "Precondition");
            Assert.That(_ints.Contains(LowEnoughButNotInSet), Is.False, "Precondition");

            // act
            IEvaluation evaluation = Specify.For(() => _ints).ThatTheSequence(x => x).Has.MinOf(LowEnoughButNotInSet).Evaluate();

            // assert
            Assert.That(evaluation.Success, Is.False);
            Assert.That(evaluation.Reason,
                Is.EqualTo(string.Format("expected _ints would have min of {0}{1} but had min of {2}.",
                    LowEnoughButNotInSet,
                    Environment.NewLine,
                    Expected)));
        }

        [Test]
        public void RejectsNonMin()
        {
            // arrange
            Assert.That(_ints.Min(), Is.EqualTo(Expected).And.Not.EqualTo(Bogus), "Precondition");
            Assert.That(_ints.Contains(Bogus), Is.True, "Precondition");

            // act
            IEvaluation evaluation = Specify.For(() => _ints).ThatTheSequence(x => x).Has.MinOf(Bogus).Evaluate();

            // assert
            Assert.That(evaluation.Success, Is.False);
            Assert.That(evaluation.Reason,
                Is.EqualTo(string.Format("expected _ints would have min of {0}{1} but had min of {2}.",
                    Bogus,
                    Environment.NewLine,
                    2)));
        }
    }
}
